package com.quanyan.stadium.service.commonComponent.impl;

import com.google.gson.Gson;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.stadium.constants.GameConstants;
import com.quanyan.stadium.entity.TbGameMqMsgLog;
import com.quanyan.stadium.entity.TbGameMqMsgLogExample;
import com.quanyan.stadium.entity.vo.StadiumNotifyMsg;
import com.quanyan.stadium.mapper.TbGameMqMsgLogMapper;
import com.quanyan.stadium.service.commonComponent.DataReductionService;
import com.quanyan.stadium.service.commonComponent.GameMQLog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2016/7/21.
 */
@Service
public class GameMQLogImpl implements GameMQLog {

    private final static Logger logger = LoggerFactory.getLogger(GameMQLogImpl.class);

    /**
     * 表示mq中的消息6分钟内如果没有被消费,则使用回调
     *
     * */
    private static final int MiddleMin = -6;

    @Autowired
    private TbGameMqMsgLogMapper tbGameMqMsgLogMapper;


    @Autowired
    private DataReductionService dataReductionService;


    @Override
    public void operateExceptionMQ() {
        TbGameMqMsgLogExample example = new TbGameMqMsgLogExample();
        TbGameMqMsgLogExample.Criteria criteria = example.createCriteria();
        criteria.andFinalStatusEqualTo(GameConstants.IS_NOT_DELETE.byteValue());
        criteria.andMsgScopeEqualTo(GameConstants.IS_NOT_DELETE.byteValue());
        criteria.andMsgSendTimeLessThanOrEqualTo(DateUtils.addTime(new Date(), MiddleMin, DateUtils.TIME_TYPE_MINUTE));
        List<TbGameMqMsgLog> msgLogList = tbGameMqMsgLogMapper.selectByExample(example);
        if (null!=msgLogList&&msgLogList.size()>0) {
            for (TbGameMqMsgLog tbGameMqMsgLog : msgLogList) {
                logger.debug("开始处理异常消息,当前消息keys:{}", tbGameMqMsgLog.getGameMsgNo());
                this.updateNotifyFinishByMsgId(tbGameMqMsgLog.getGameMsgNo());
                try{
                    Gson gson = new Gson();
                    Class clazz = dataReductionService.getClass();
                    Method m1 = clazz.getDeclaredMethod(tbGameMqMsgLog.getNotifyMethod(), StadiumNotifyMsg.class);
                    m1.invoke(dataReductionService, gson.fromJson(tbGameMqMsgLog.getMsgBody(), StadiumNotifyMsg.class));
                } catch (Exception e) {
                    logger.error("处理异常消息时,反射机制出错,错误原因:{}", e);
                }

            }
        }
    }

    @Override
    public void initMQLog(TbGameMqMsgLog tbGameMqMsgLog) {
        tbGameMqMsgLog.setMsgSendTime(new Date());
        tbGameMqMsgLogMapper.insertSelective(tbGameMqMsgLog);

    }

    @Override
    public TbGameMqMsgLog getTbGameMqMsgLogByMsgId(String msgKeys) {
        TbGameMqMsgLogExample example = new TbGameMqMsgLogExample();
        TbGameMqMsgLogExample.Criteria criteria = example.createCriteria();
        criteria.andGameMsgNoEqualTo(msgKeys);
        List<TbGameMqMsgLog> msgLogList = tbGameMqMsgLogMapper.selectByExample(example);
        if (null!=msgLogList&&msgLogList.size()==1) {
            return msgLogList.get(0);
        }
        return null;
    }

    @Override
    public void updateMqFinishByMsgId(String msgKeys) {

        TbGameMqMsgLog tbGameMqMsgLog = new TbGameMqMsgLog();
        tbGameMqMsgLog.setMsgConsumerTime(new Date());
        tbGameMqMsgLog.setIsConsumer(GameConstants.IS_DELETE.byteValue());
        tbGameMqMsgLog.setFinalStatus(GameConstants.IS_DELETE.byteValue());

        TbGameMqMsgLogExample example = new TbGameMqMsgLogExample();
        TbGameMqMsgLogExample.Criteria criteria = example.createCriteria();
        criteria.andGameMsgNoEqualTo(msgKeys);
        tbGameMqMsgLogMapper.updateByExampleSelective(tbGameMqMsgLog, example);
    }

    @Override
    public void updateNotifyFinishByMsgId(String msgKeys) {
        TbGameMqMsgLog tbGameMqMsgLog = new TbGameMqMsgLog();
        tbGameMqMsgLog.setFinalStatus(GameConstants.IS_DELETE.byteValue());
        tbGameMqMsgLog.setNotifyOperateTime(new Date());
        tbGameMqMsgLog.setMsgOperateType(GameConstants.IS_DELETE);

        TbGameMqMsgLogExample example = new TbGameMqMsgLogExample();
        TbGameMqMsgLogExample.Criteria criteria = example.createCriteria();
        criteria.andGameMsgNoEqualTo(msgKeys);
        tbGameMqMsgLogMapper.updateByExampleSelective(tbGameMqMsgLog, example);
    }

    @Override
    public boolean isConsumerFinish(String msgKeys) {
        TbGameMqMsgLogExample example = new TbGameMqMsgLogExample();
        TbGameMqMsgLogExample.Criteria criteria = example.createCriteria();
        criteria.andGameMsgNoEqualTo(msgKeys);
        List<TbGameMqMsgLog> msgLogList = tbGameMqMsgLogMapper.selectByExample(example);
        if (null!=msgLogList&&msgLogList.size()==1) {
            if (msgLogList.get(0).getFinalStatus().intValue() == GameConstants.IS_DELETE) {
                return true;
            }
        }
        return false;
    }

    @Override
    public StadiumNotifyMsg getStadiumMsgModelByMsgId(String msgKeys) throws Exception{
        StadiumNotifyMsg stadiumMsgModel = new StadiumNotifyMsg();
        Gson gson = new Gson();
        TbGameMqMsgLogExample example = new TbGameMqMsgLogExample();
        TbGameMqMsgLogExample.Criteria criteria = example.createCriteria();
        criteria.andGameMsgNoEqualTo(msgKeys);
        List<TbGameMqMsgLog> msgLogList = tbGameMqMsgLogMapper.selectByExample(example);
        if (null!=msgLogList&&msgLogList.size()==1)  {
            return gson.fromJson(msgLogList.get(0).getMsgBody(), StadiumNotifyMsg.class);
        }
        return stadiumMsgModel;
    }
}
